package com.yuehuanghun.framework.util.http;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.Date;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import com.yuehuanghun.framework.util.DateUtils;

/**
 * 由SecurityInterceptor设置HttpServletRequest、HttpServletResponse
 * 
 * @author yuehuanghun
 * 
 */
public class RequestUtils {
	private static ThreadLocal<HttpServletRequest> reqLocal = new ThreadLocal<HttpServletRequest>();
	private static ThreadLocal<HttpServletResponse> responseLocal = new ThreadLocal<HttpServletResponse>();

	public static void setHttpServletRequest(HttpServletRequest request) {
		reqLocal.set(request);
	}

	public static void clearHttpReqResponse() {
		reqLocal.remove();
		responseLocal.remove();
	}

	public static void setHttpServletResponse(HttpServletResponse response) {
		responseLocal.set(response);
	}

	/**
	 * 当前线程中的HttpServletRequest
	 * 
	 * @return
	 */
	public static HttpServletRequest getHttpServletRequest() {
		return (HttpServletRequest) reqLocal.get();
	}

	/**
	 * 当前线程中的HttpServletResponse
	 * 
	 * @return
	 */
	public static HttpServletResponse getHttpServletResponse() {
		return (HttpServletResponse) responseLocal.get();
	}

	public static String getString(HttpServletRequest request, String key,
			String defaultValue, boolean b) {
		String value = request.getParameter(key);
		if (StringUtils.isEmpty(value)) {
			return defaultValue;
		}
		if (b) {
			return value.replace("'", "''").trim();
		}
		return value.trim();
	}

	public static String getString(HttpServletRequest request, String key) {
		return getString(request, key, "", true);
	}

	public static String getString(HttpServletRequest request, String key,
			boolean b) {
		return getString(request, key, "", b);
	}

	public static String getString(HttpServletRequest request, String key,
			String defaultValue) {
		return getString(request, key, defaultValue, true);
	}

	public static String getStringAry(HttpServletRequest request, String key) {
		String[] aryValue = request.getParameterValues(key);
		if ((aryValue == null) || (aryValue.length == 0)) {
			return "";
		}
		String tmp = "";
		for (String v : aryValue) {
			if ("".equals(tmp)) {
				tmp = tmp + v;
			} else {
				tmp = tmp + "," + v;
			}
		}
		return tmp;
	}

	public static String getLowercaseString(HttpServletRequest request,
			String key) {
		return getString(request, key).toLowerCase();
	}

	public static int getInt(HttpServletRequest request, String key) {
		return getInt(request, key, 0);
	}

	public static int getInt(HttpServletRequest request, String key,
			int defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		return Integer.parseInt(str);
	}

	public static long getLong(HttpServletRequest request, String key) {
		return getLong(request, key, 0L);
	}

	public static Long[] getLongAry(HttpServletRequest request, String key) {
		String[] aryKey = request.getParameterValues(key);
		if (aryKey == null || aryKey.length == 0) {
			return null;
		}
		Long[] aryLong = new Long[aryKey.length];
		for (int i = 0; i < aryKey.length; i++) {
			aryLong[i] = Long.valueOf(Long.parseLong(aryKey[i]));
		}
		return aryLong;
	}

	public static Long[] getLongAryByStr(HttpServletRequest request, String key) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		String[] aryId = str.split(",");
		Long[] lAryId = new Long[aryId.length];
		for (int i = 0; i < aryId.length; i++) {
			lAryId[i] = Long.valueOf(Long.parseLong(aryId[i]));
		}
		return lAryId;
	}

	/**
	 * arrayStr 是一个可以被分割的字符串
	 * 
	 * @param arrayStr
	 *            一个或多个值
	 * @return
	 */
	public static Long[] getLongAryByStr(String arrayStr) {
		if (StringUtils.isEmpty(arrayStr)) {
			return null;
		}
		String[] aryId = arrayStr.split(",");
		Long[] lAryId = new Long[aryId.length];
		for (int i = 0; i < aryId.length; i++) {
			lAryId[i] = Long.valueOf(Long.parseLong(aryId[i]));
		}
		return lAryId;
	}

	public static String[] getStringAryByStr(HttpServletRequest request,
			String key) {
		String str = request.getParameter(key);
		return getStringAryByStr(str);
	}
	
	/**
	 * arrayStr 是一个可以被分割的字符串
	 * 
	 * @param arrayStr
	 *            一个或多个值
	 * @return
	 */
	public static String[] getStringAryByStr(String arryStr) {
		String str = arryStr;
		if (StringUtils.isEmpty(str)) {
			return new String[0];
		}
		String[] aryId = str.split(",");
		String[] lAryId = new String[aryId.length];
		for (int i = 0; i < aryId.length; i++) {
			lAryId[i] = aryId[i];
		}
		return lAryId;
	}

	public static Integer[] getIntAry(HttpServletRequest request, String key) {
		String[] aryKey = request.getParameterValues(key);
		if (aryKey == null || aryKey.length == 0) {
			return null;
		}
		Integer[] aryInt = new Integer[aryKey.length];
		for (int i = 0; i < aryKey.length; i++) {
			aryInt[i] = Integer.valueOf(Integer.parseInt(aryKey[i]));
		}
		return aryInt;
	}

	public static Float[] getFloatAry(HttpServletRequest request, String key) {
		String[] aryKey = request.getParameterValues(key);
		if (aryKey == null || aryKey.length == 0) {
			return null;
		}
		Float[] fAryId = new Float[aryKey.length];
		for (int i = 0; i < aryKey.length; i++) {
			fAryId[i] = Float.valueOf(Float.parseFloat(aryKey[i]));
		}
		return fAryId;
	}

	public static long getLong(HttpServletRequest request, String key,
			long defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str) || "null".equals(str)) {
			return defaultValue;
		}
		return Long.parseLong(str.trim());
	}

	public static Long getLong(HttpServletRequest request, String key,
			Long defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		return Long.valueOf(Long.parseLong(str.trim()));
	}

	public static float getFloat(HttpServletRequest request, String key) {
		return getFloat(request, key, 0.0F);
	}

	public static double getDouble(HttpServletRequest request, String key) {
		return getDouble(request, key, 0.0d);
	}

	public static double getDouble(HttpServletRequest request, String key,
			double defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		return Double.parseDouble(request.getParameter(key));
	}

	public static float getFloat(HttpServletRequest request, String key,
			float defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		return Float.parseFloat(request.getParameter(key));
	}

	public static boolean getBoolean(HttpServletRequest request, String key) {
		return getBoolean(request, key, false);
	}

	public static boolean getBoolean(HttpServletRequest request, String key,
			boolean defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		if (StringUtils.isNumeric(str)) {
			return Integer.parseInt(str) == 1;
		}
		return Boolean.parseBoolean(str);
	}

	public static Short getShort(HttpServletRequest request, String key) {
		return getShort(request, key, Short.valueOf((short) 0));
	}

	public static Short getShort(HttpServletRequest request, String key,
			Short defaultValue) {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return defaultValue;
		}
		return Short.valueOf(Short.parseShort(str));
	}

	public static Date getDate(HttpServletRequest request, String key,
			String style) throws ParseException {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		if (StringUtils.isEmpty(style)) {
			style = "yyyy-MM-dd HH:mm:ss";
		}
		return DateUtils.parseDate(str, style);
	}

	public static Date getDate(HttpServletRequest request, String key)
			throws ParseException {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		return DateUtils.parseDate(str);
	}

	public static Date getTimestamp(HttpServletRequest request, String key)
			throws ParseException {
		String str = request.getParameter(key);
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		return DateUtils.parseDate(str);
	}

	public static String getUrl(HttpServletRequest request) {
		StringBuffer urlThisPage = new StringBuffer();
		urlThisPage.append(request.getRequestURI());
		Enumeration<String> e = request.getParameterNames();
		String para = "";
		String values = "";
		urlThisPage.append("?");
		while (e.hasMoreElements()) {
			para = e.nextElement();
			values = request.getParameter(para);
			urlThisPage.append(para);
			urlThisPage.append("=");
			urlThisPage.append(values);
			urlThisPage.append("&");
		}
		return urlThisPage.substring(0, urlThisPage.length() - 1);
	}

	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if ((ip == null) || (ip.length() == 0)
				|| ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getHeader("Proxy-Client-IP");
        } else {
            String[] split = ip.split(",");
            for (String proxyIp : split) {
                if (proxyIp != null && !proxyIp.trim().equals("") && !"unknown".equalsIgnoreCase(proxyIp)) {
                    ip = proxyIp.trim();
                    break; //取最先合法的
                }
            }
        }
		if ((ip == null) || (ip.length() == 0)
				|| ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if ((ip == null) || (ip.length() == 0)
				|| ("unknown".equalsIgnoreCase(ip))) {
			ip = request.getRemoteAddr();
			
			if("0:0:0:0:0:0:0:1".equals(ip)){
				ip="127.0.0.1";
			}
		}
		return ip;
	}

	public static String getUserAgent(HttpServletRequest request) {
		return request.getHeader("User-Agent");
	}

	public static String getBrowserName(HttpServletRequest request) {
		String agent = getUserAgent(request);
		if(agent==null){
			return "unknown";
		}
		agent = agent.toLowerCase();
		if (agent.indexOf("msie 7") > -1) {
			return "ie7";
		} else if (agent.indexOf("msie 8") > -1) {
			return "ie8";
		} else if (agent.indexOf("msie 9") > -1) {
			return "ie9";
		} else if (agent.indexOf("msie 10") > -1) {
			return "ie10";
		} else if (agent.indexOf("msie") > -1) {
			return "ie";
		} else if (agent.indexOf("chrome") > -1) {
			return "chrome";
		}  else if (agent.indexOf("opera") > -1) {
			return "opera";
		} else if (agent.indexOf("firefox") > -1) {
			return "firefox";
		} else if (agent.indexOf("webkit") > -1) {
			return "webkit";
		} else if (agent.indexOf("gecko") > -1 && agent.indexOf("rv:11") > -1) {
			return "ie11";
		} else if(agent.indexOf("Trident") > -1){
			return "MS Edage";
		}else {
			return "Others";
		}
	}
	
	/**
	 * 初始化下载，将文件根据不同的浏览器进行编码并设置响应头
	 * @param request
	 * @param response
	 * @param fileName 下载的文件名
	 * @throws UnsupportedEncodingException
	 */
	public static void downloadInit(HttpServletRequest request,
			HttpServletResponse response, String fileName)
			throws UnsupportedEncodingException {
		response.setContentType("APPLICATION/OCTET-STREAM");
		if (StringUtils.isNotEmpty(fileName)) {
			String fileNameLower = fileName.toLowerCase();
			if (fileNameLower.endsWith(".apk")) {
				response.setContentType("application/vnd.android.package-archive");
			} else if(fileNameLower.endsWith(".pdf")) {
				response.setContentType("application/pdf");
			}
		}
		String filedisplay = fileName;
		String agent = request.getHeader("USER-AGENT");
		if (agent != null && agent.indexOf("MSIE") == -1
				&& !agent.contains("Trident")) {
			String enableFileName = "=?UTF-8?B?"
					+ new String(Base64.encodeBase64(filedisplay
							.getBytes("UTF-8"))) + "?=";
			response.setHeader("Content-Disposition", "attachment; filename="
					+ enableFileName);
		} else {
			filedisplay = URLEncoder.encode(filedisplay, "UTF-8");
			response.addHeader("Content-Disposition", "attachment;filename="
					+ filedisplay);
		}
	}
	
	/**
     * 是否是Ajax异步请求
     * 
     * @param request
     */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		String accept = request.getHeader("accept");
		if (accept != null && accept.indexOf("application/json") != -1) {
			return true;
		}

		String xRequestedWith = request.getHeader("X-Requested-With");
		if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
			return true;
		}

		String uri = request.getRequestURI();
		if (com.yuehuanghun.framework.util.StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) {
			return true;
		}

		String ajax = request.getParameter("__ajax");
		if (com.yuehuanghun.framework.util.StringUtils.inStringIgnoreCase(ajax, "json", "xml")) {
			return true;
		}
		return false;
	}
}
